package com.tuniu.agents.advisor;

import com.google.common.base.Strings;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.Assert;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Redis implementation for storing global environment variables for the agent
 */
public class RedisEnvironmentMemory implements ChatEnvironmentMemory {

    private static final String REDIS_KEY_PREFIX = "ChatExtendParam:";

    private final RedisTemplate<String, Map<String, Object>> redisTemplate;

    public RedisEnvironmentMemory(RedisTemplate<String, Map<String, Object>> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void add(String conversationId, Map<String, Object> message) {
        Assert.noNullElements(message.values(), "message values cannot contain null elements");
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        hashOps.putAll(key(conversationId), message);
        redisTemplate.expire(key(conversationId), 7, TimeUnit.DAYS);
    }

    @Override
    public Map<String, Object> get(String conversationId) {
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        return hashOps.entries(key(conversationId));
    }

    @Override
    public Object get(String conversationId, String key) {
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        return hashOps.get(key(conversationId), key);
    }

    @Override
    public Boolean exist(String conversationId) {
        return redisTemplate.hasKey(key(conversationId));
    }

    @Override
    public void clear(String conversationId, String key) {
        Assert.notNull(conversationId, "conversationId cannot be null");
        Assert.notNull(key, "key cannot be null");

        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        String redisKey = key(conversationId);

        if (redisTemplate.hasKey(redisKey)) {
            hashOps.delete(redisKey, key);
        }
    }

    @Override
    public void clear(String conversationId) {
        redisTemplate.delete(key(conversationId));
    }

    public String key(String conversationId) {
        if (Strings.isNullOrEmpty(conversationId)) {
            return null;
        }
        return REDIS_KEY_PREFIX + conversationId;
    }
}